<template>
  <div class="page-container">
    <el-container>
      <el-aside width="200px" class="page-aside" v-drag v-collapse>
        <el-row>
          <el-input
            placeholder="菜单搜索"
            v-model="filterText"
            style="margin-right: 10px"
          ></el-input>
        </el-row>
        <el-row class="page-aside-grow">
          <el-tree 
            ref="tree"
            v-loading="menuLoading"
            element-loading-text="数据加载中..."
            class="filter-tree" 
            :data="treeData" 
            node-key="id"
            :props="treeProps" 
            :expand-on-click-node="false" 
            :highlight-current="true" 
            :default-expanded-keys="treeExpand"
            @node-click="nodeClick" 
            :filter-node-method="filterNode"
          >
          </el-tree>
        </el-row>
      </el-aside>
      <el-main class="page-main">
        <!--表格内容栏-->
        <cm-table
          ref="dataTable"
          pkName="id"
          :filters="filters"
          :filterFields="filterFields"
          :columns="columns"
          :defaultSort="defaultSort"
          @handleTableOperator="handleTableOperator"
          @handleAjaxSuccess="handleAjaxSuccess"
        ></cm-table>
      </el-main>
    </el-container>
      
    <!--新增编辑界面-->
    <el-dialog
      :title="operator"
      width="65%"
      v-model="dialogVisible"

      :close-on-click-modal="false"
      destroy-on-close
      fullscreen
    >
      <div
        class="dialog-box"
        v-loading="dialogLoading"
        element-loading-text="数据加载中..."
      >
        <cm-form
          ref="dataForm"
          v-model="formData"
          :fields="columns"
          :rules="rules"
          :disabled="formDisabled"
        ></cm-form>
        <cm-edit-table
          ref="editTable"
          width="100%"
          tips="权限按钮"
          :columns="privilegeColumns"
          :rules="privilegeRules"
          :dataList="formData.privileges"
        ></cm-edit-table>
      </div>
      <template #footer>
        <el-button
          size="large"
          type="info"
          @click="dialogVisible=false"
        >取消</el-button>
        <el-button
          size="large"
          type="primary"
          :loading="editLoading"
          @click="submitForm"
        >提交
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import {onMounted, ref, watch} from 'vue';
import {ElMessage, ElMessageBox} from "element-plus";
import api from '@/http/api';

// 增加/修改表单数据
const defaultFormData = ref({
  id: '',
  parentId: '',
  type: '1',
  name: '',
  vuePath: '',
  url: '',
  valid: '1',
  needPermit: '1',
  ordinal: 1,
  privileges: []
});

const filterText = ref('');
const treeData = ref([]);
const treeProps = ref({
  children: 'children',
  label: 'text'
});
const treeExpand = ref(['0']);
const menuLoading = ref(true);

const parentId = ref('');
const currentId = ref('');

const filters = ref({
  name: '',
  type: '',
  valid: ''
});
const filterFields = ref([
  {prop: "name", label: "菜单名称"},
]);
const columns = ref([
  {prop: "parentId", label: "上级菜单", minWidth: 160, type: 'tree', dataUrl: '/menu/queryTree', table: false, leafSelect: false},
  {prop: "name", label: "名称", minWidth: 160},
  {prop: "type", label: "类型", width: 70, align: 'center', type: 'radio', dicCode: 'dicMenuType'},
  {prop: "vuePath", label: "菜单路径", minWidth: 160},
  {prop: "url", label: "数据地址", minWidth: 160},
  {prop: "valid", label: "有效", width: 70, align: 'center', type: 'radio', dicCode: 'dicValid'},
  {prop: "ordinal", label: "排序", width: 70, type: 'number' },
  {prop: "createTime", label: "创建时间", width: 160, onlyShow: true }
]);
const operator = ref('');
const dialogVisible = ref(false);
const dialogLoading = ref(false);
const editLoading = ref(false);
const formData = ref(defaultFormData.value);
const rules = ref({
  name: [{required: true, message: '请输入菜单名称', trigger: 'blur'}],
  type: [{required: true, message: '请选择菜单类型', trigger: ['blur', 'change']}],
  valid: [{required: true, message: '请选择是否有效', trigger: ['blur', 'change']}],
  ordinal: [
    {required: true, message: '请输入排序', trigger: 'blur'},
    {type: 'number', message: '排序必须为数字', trigger: 'blur'}]
});

const privilegeColumns = ref([
  {prop: "name", label: "名称", minWidth: 110},
  {prop: "type", label: "类型", width: 80, type: 'select', dicCode: 'dicPrivilegeType'},
  {prop: "buttonLevel", label: "按钮级别", width: 80, type: 'select', dicCode: 'dicButtonLevel', show: (data) => data['type'] === '1'},
  {prop: "buttonClass", label: "按钮样式", width: 80, type: 'select', dicCode: 'dicButtonClass', show: (data) => data['type'] === '1'},
  {prop: "buttonIcon", label: "按钮图标", width: 130, type: 'select', dicCode: 'dicButtonIcon', allowCreate: true, show: (data) => data['type'] === '1'},
  {prop: "buttonType", label: "按钮类型", width: 130, type: 'select', dicCode: 'dicButtonType', allowCreate: true, show: (data) => data['type'] === '1'},
  {prop: "selectedMode", label: "选择方式", width: 110, type: 'select', dicCode: 'dicSelectedMode', show: (data) => data['type'] === '1'},
  {prop: "dataSourUrl", label: "数据来源地址", minWidth: 140, show: (data) => data['type'] === '1'},
  {prop: "dataDestUrl", label: "数据目标地址", minWidth: 140, show: (data) => data['type'] === '1'},
  {prop: "clickTips", label: "点击提示", minWidth: 120, show: (data) => data['type'] === '1'},
  {prop: "ordinal", label: "排序", width: 60, type: 'number'},
]);
const privilegeRules = ref({
  operatorName: [{required: true, message: '请输入操作名称', trigger: 'blur'}],
  buttonName: [{required: true, message: '请输入按钮名称', trigger: 'blur'}],
  buttonLevel: [{required: true, message: '请选择按钮级别', trigger: 'change'}],
  selectedMode: [{required: true, message: '请选择选择方式', trigger: 'change'}],
  ordinal: [
    {required: true, message: '请输入排序', trigger: 'blur'},
    {type: 'number', message: '排序必须为数字', trigger: 'blur'}]
});

const formDisabled = ref(false);
const defaultSort = ref({prop: 'ordinal', order: 'ascending'});
const tree = ref();
const dataTable = ref();
const dataForm = ref();
const editTable = ref();

const filterNode = (value, data) => {
  if (!value) return true;
  return data.text.indexOf(value) !== -1;
};

const nodeClick = (data) => {
  filters.value.parentId = data.id;
  parentId.value = data.pid || 0;
  currentId.value = data.id || 0;
  dataTable.value.findPage();
};

// 显示操作界面
const handleTableOperator = (button, row) => {
  operator.value = button.name
  formData.value = Object.assign({}, defaultFormData.value);

  if (button.buttonType === 'edit') {
    dialogLoading.value = true;
    api.post('/menu/queryBy', {id: row.id}).then(res => {
      dialogLoading.value = false;
      formData.value = Object.assign({}, res.data, {button: button});
    }).catch(() => {
      dialogLoading.value = false;
    });
  } else if (button.buttonType === 'copy') {
    dialogLoading.value = true;
    api.post('/menu/queryBy', {id: row.id}).then(res => {
      dialogLoading.value = false;
      let result = res.data;
      result.id = '';
      (result.privileges || []).forEach(item => item.id = '');
      formData.value = Object.assign({}, result, {button: button});
    }).catch(() => {
      dialogLoading.value = false;
    });
  } else if (button.buttonType === 'add') {
    if (parentId.value === '') {
      ElMessage.warning('请先选择右左侧菜单！');
      return;
    }
    formData.value = Object.assign({},
      defaultFormData.value,
      {button: button, parentId: parentId.value || 0});
  } else if (button.buttonType === 'addSub') {
    if (currentId.value === '') {
      ElMessage.warning('请先选择右左侧菜单！');
      return;
    }
    formData.value = Object.assign({},
      defaultFormData.value,
      {button: button, parentId: currentId.value || 0});
  } else {
    formData.value = Object.assign({button: button}, defaultFormData.value);
  }

  dialogVisible.value = true
};

const handleAjaxSuccess = () => {
  loadTreeData();
};

// 编辑
const submitForm = () => {
    dataForm.value && dataForm.value.validate((valid) => {
    if (valid) {
      editTable.value.validate(valid => {
        if (valid) {
          ElMessageBox.confirm('请确认是否提交？', '提示', {type: 'info'}).then(() => {
            editLoading.value = true;
            formData.value.privileges = editTable.value.getList() || [];
            api.post(formData.value.button.dataDestUrl, formData.value).then(res => {
              ElMessage.success(res.message);
              dialogVisible.value = false;
              editLoading.value = false;
              dataTable.value.findPage();
              loadTreeData();
            }).catch(() => {
              editLoading.value = false;
            })
          }).catch(()=>{});
        }
      });
    }
  })
};

const loadTreeData = () => {
  menuLoading.value = true;
  api.post('/menu/queryTree').then(res => {
    treeData.value = [res.data];
    menuLoading.value = false;
  }).catch(() => {
    menuLoading.value = false;
  });
};

watch(() => filterText.value, (val) => {
  tree.value.filter(val)
});

onMounted(() => {
  loadTreeData();
});
</script>

<style scoped>
.dialog-box {
  display: flex;
  flex-direction: column;
}
</style>